home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 001-025 / scopedisk4 / patch / util.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  8KB  |  410 lines

  1. #include "EXTERN.h"
  2. #include "common.h"
  3. #include "INTERN.h"
  4. #include "util.h"
  5.  
  6. /* Rename a file, copying it if necessary. */
  7.  
  8. int
  9. move_file(from,to)
  10. char *from, *to;
  11. {
  12.     char bakname[512];
  13.     Reg1 char *s;
  14.     Reg2 int i;
  15.     Reg3 int fromfd;
  16.  
  17.     /* to stdout? */
  18.  
  19.     if (strEQ(to, "-")) {
  20. #ifdef DEBUGGING
  21.     if (debug & 4)
  22.         say2("Moving %s to stdout.\n", from);
  23. #endif
  24.     fromfd = open(from, 0);
  25.     if (fromfd < 0)
  26.         fatal2("patch: internal error, can't reopen %s\n", from);
  27.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  28.         if (write(1, buf, i) != 1)
  29.         fatal1("patch: write failed\n");
  30.     Close(fromfd);
  31.     return 0;
  32.     }
  33.  
  34.     Strcpy(bakname, to);
  35.     Strcat(bakname, origext?origext:ORIGEXT);
  36. #ifdef AMIGA
  37.     if (!dfindOne(&filestat, to, 1)) {    /* output file exists */
  38.     unlink(bakname);
  39. #else
  40.     if (stat(to, &filestat) >= 0) {    /* output file exists */
  41.     dev_t to_device = filestat.st_dev;
  42.     ino_t to_inode  = filestat.st_ino;
  43.     char *simplename = bakname;
  44.     
  45.     for (s=bakname; *s; s++) {
  46.         if (*s == '/')
  47.         simplename = s+1;
  48.     }
  49.     /* find a backup name that is not the same file */
  50.     while (stat(bakname, &filestat) >= 0 &&
  51.         to_device == filestat.st_dev && to_inode == filestat.st_ino) {
  52.         for (s=simplename; *s && !islower(*s); s++) ;
  53.         if (*s)
  54.         *s = toupper(*s);
  55.         else
  56.         Strcpy(simplename, simplename+1);
  57.     }
  58.     while (unlink(bakname) >= 0) ;    /* while() is for benefit of Eunice */
  59. #endif
  60. #ifdef DEBUGGING
  61.     if (debug & 4)
  62.         say3("Moving %s to %s.\n", to, bakname);
  63. #endif
  64. #ifdef AMIGA
  65.     if (rename(to, bakname)) {
  66.         say3("patch: can't backup %s, output is in %s\n",
  67.         to, from);
  68.         return -1;
  69.     }
  70. #else
  71.     if (link(to, bakname) < 0) {
  72.         say3("patch: can't backup %s, output is in %s\n",
  73.         to, from);
  74.         return -1;
  75.     }
  76.     while (unlink(to) >= 0) ;
  77. #endif
  78.     }
  79. #ifdef DEBUGGING
  80.     if (debug & 4)
  81.     say3("Moving %s to %s.\n", from, to);
  82. #endif
  83. #ifdef AMIGA
  84.     if (rename(from, to)) {        /* different file system? */
  85. #else
  86.     if (link(from, to) < 0) {        /* different file system? */
  87. #endif
  88.     Reg4 int tofd;
  89.     
  90.     tofd = creat(to, 0666);
  91.     if (tofd < 0) {
  92.         say3("patch: can't create %s, output is in %s.\n",
  93.           to, from);
  94.         return -1;
  95.     }
  96.     fromfd = open(from, 0);
  97.     if (fromfd < 0)
  98.         fatal2("patch: internal error, can't reopen %s\n", from);
  99.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  100.         if (write(tofd, buf, i) != i)
  101.         fatal1("patch: write failed\n");
  102.     Close(fromfd);
  103.     Close(tofd);
  104.     }
  105.     Unlink(from);
  106.     return 0;
  107. }
  108.  
  109. /* Copy a file. */
  110.  
  111. void
  112. copy_file(from,to)
  113. char *from, *to;
  114. {
  115.     Reg3 int tofd;
  116.     Reg2 int fromfd;
  117.     Reg1 int i;
  118.     
  119.     tofd = creat(to, 0666);
  120.     if (tofd < 0)
  121.     fatal2("patch: can't create %s.\n", to);
  122.     fromfd = open(from, 0);
  123.     if (fromfd < 0)
  124.     fatal2("patch: internal error, can't reopen %s\n", from);
  125.     while ((i=read(fromfd, buf, sizeof buf)) > 0)
  126.     if (write(tofd, buf, i) != i)
  127.         fatal2("patch: write (%s) failed\n", to);
  128.     Close(fromfd);
  129.     Close(tofd);
  130. }
  131.  
  132. /* Allocate a unique area for a string. */
  133.  
  134. char *
  135. savestr(s)
  136. Reg1 char *s;
  137. {
  138.     Reg3 char *rv;
  139.     Reg2 char *t;
  140.  
  141.     if (!s)
  142.     s = "Oops";
  143.     t = s;
  144.     while (*t++);
  145.     rv = malloc((MEM) (t - s));
  146.     if (rv == Nullch) {
  147.     if (using_plan_a)
  148.         out_of_mem = TRUE;
  149.     else
  150.         fatal1("patch: out of memory (savestr)\n");
  151.     }
  152.     else {
  153.     t = rv;
  154.     while (*t++ = *s++);
  155.     }
  156.     return rv;
  157. }
  158.  
  159. #ifdef lint
  160. #ifdef CANVARARG
  161.  
  162. /*VARARGS ARGSUSED*/
  163. say(pat) char *pat; { ; }
  164. /*VARARGS ARGSUSED*/
  165. fatal(pat) char *pat; { ; }
  166. /*VARARGS ARGSUSED*/
  167. ask(pat) char *pat; { ; }
  168.  
  169. #endif
  170. #else
  171.  
  172. /* Vanilla terminal output (buffered). */
  173.  
  174. void
  175. say(pat,arg1,arg2,arg3)
  176. char *pat;
  177. int arg1,arg2,arg3;
  178. {
  179.     fprintf(stderr, pat, arg1, arg2, arg3);
  180.     Fflush(stderr);
  181. }
  182.  
  183. /* Terminal output, pun intended. */
  184.  
  185. void                /* very void */
  186. fatal(pat,arg1,arg2,arg3)
  187. char *pat;
  188. int arg1,arg2,arg3;
  189. {
  190.     void my_exit();
  191.  
  192.     say(pat, arg1, arg2, arg3);
  193.     my_exit(1);
  194. }
  195.  
  196. #ifdef AMIGA
  197. /* Ask user for a file name */
  198.  
  199. void
  200. fileRequest(prompt)
  201. char *prompt;
  202. {
  203.     if(!stdfile(prompt, NULL, NULL, buf)) {
  204.     strcpy(buf,"\n");
  205.     }
  206. }
  207. #endif
  208.  
  209. /* Get a response from the user, somehow or other. */
  210.  
  211. #ifdef AMIGA
  212. void
  213. ask(pat,arg1,arg2,arg3)
  214. char *pat;
  215. int arg1,arg2,arg3;
  216. {
  217.     Sprintf(buf, pat, arg1, arg2, arg3);
  218.     if(simpleRequest(buf)) {
  219.     strcpy(buf,"y\n");
  220.     } else {
  221.     strcpy(buf,"n\n");
  222.     }
  223. }
  224. #else
  225. void
  226. ask(pat,arg1,arg2,arg3)
  227. char *pat;
  228. int arg1,arg2,arg3;
  229. {
  230.     int ttyfd;
  231.     int r;
  232.     bool tty2 = isatty(2);
  233.  
  234.     Sprintf(buf, pat, arg1, arg2, arg3);
  235.     Fflush(stderr);
  236.     write(2, buf, strlen(buf));
  237.     if (tty2) {                /* might be redirected to a file */
  238.     r = read(2, buf, sizeof buf);
  239.     }
  240.     else if (isatty(1)) {        /* this may be new file output */
  241.     Fflush(stdout);
  242.     write(1, buf, strlen(buf));
  243.     r = read(1, buf, sizeof buf);
  244.     }
  245.     else if ((ttyfd = open("/dev/tty", 2)) >= 0 && isatty(ttyfd)) {
  246.                     /* might be deleted or unwriteable */
  247.     write(ttyfd, buf, strlen(buf));
  248.     r = read(ttyfd, buf, sizeof buf);
  249.     Close(ttyfd);
  250.     }
  251.     else if (isatty(0)) {        /* this is probably patch input */
  252.     Fflush(stdin);
  253.     write(0, buf, strlen(buf));
  254.     r = read(0, buf, sizeof buf);
  255.     }
  256.     else {                /* no terminal at all--default it */
  257.     buf[0] = '\n';
  258.     r = 1;
  259.     }
  260.     if (r <= 0)
  261.     buf[0] = 0;
  262.     else
  263.     buf[r] = '\0';
  264.     if (!tty2)
  265.     say1(buf);
  266. }
  267. #endif lint
  268.  
  269. /* How to handle certain events when not in a critical region. */
  270.  
  271. void
  272. set_signals()
  273. {
  274.     void my_exit();
  275.  
  276. #ifndef lint
  277. #ifndef AMIGA
  278.     if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
  279.     Signal(SIGHUP, my_exit);
  280. #endif
  281.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  282.     Signal(SIGINT, my_exit);
  283. #endif
  284. }
  285.  
  286. /* How to handle certain events when in a critical region. */
  287.  
  288. void
  289. ignore_signals()
  290. {
  291. #ifndef lint
  292. #ifndef AMIGA
  293.     Signal(SIGHUP, SIG_IGN);
  294. #endif
  295.     Signal(SIGINT, SIG_IGN);
  296. #endif
  297. }
  298.  
  299. /* Make sure we'll have the directories to create a file. */
  300.  
  301. void
  302. makedirs(filename,striplast)
  303. Reg1 char *filename;
  304. bool striplast;
  305. {
  306.     char tmpbuf[256];
  307.     Reg2 char *s = tmpbuf;
  308.     char *dirv[20];
  309.     Reg3 int i;
  310.     Reg4 int dirvp = 0;
  311.  
  312.     while (*filename) {
  313.     if (*filename == '/') {
  314.         filename++;
  315.         dirv[dirvp++] = s;
  316.         *s++ = '\0';
  317.     }
  318.     else {
  319.         *s++ = *filename++;
  320.     }
  321.     }
  322.     *s = '\0';
  323.     dirv[dirvp] = s;
  324.     if (striplast)
  325.     dirvp--;
  326.     if (dirvp < 0)
  327.     return;
  328. #ifdef AMIGA
  329.     for (i=0; i<=dirvp; i++) {
  330.     strcpy(buf, tmpbuf);
  331.     *dirv[i] = '/';
  332.     mkdir(buf);
  333.     }
  334. #else
  335.     strcpy(buf, "mkdir");
  336.     s = buf;
  337.     for (i=0; i<=dirvp; i++) {
  338.     while (*s) s++;
  339.     *s++ = ' ';
  340.     strcpy(s, tmpbuf);
  341.     *dirv[i] = '/';
  342.     }
  343.     system(buf);
  344. #endif
  345. }
  346.  
  347. /* Make filenames more reasonable. */
  348.  
  349. char *
  350. fetchname(at,strip_leading,assume_exists)
  351. char *at;
  352. int strip_leading;
  353. int assume_exists;
  354. {
  355.     char *s;
  356.     char *name;
  357.     Reg1 char *t;
  358.     char tmpbuf[200];
  359.  
  360.     if (!at)
  361.     return Nullch;
  362.     s = savestr(at);
  363.     for (t=s; isspace(*t); t++) ;
  364.     name = t;
  365. #ifdef DEBUGGING
  366.     if (debug & 128)
  367.     say4("fetchname %s %d %d\n",name,strip_leading,assume_exists);
  368. #endif
  369.     if (strnEQ(name, "/dev/null", 9))    /* so files can be created by diffing */
  370.     return Nullch;            /*   against /dev/null. */
  371.     for (; *t && !isspace(*t); t++)
  372.     if (*t == '/')
  373.         if (--strip_leading >= 0)
  374.         name = t+1;
  375.     *t = '\0';
  376.     if (name != s && *s != '/') {
  377.     name[-1] = '\0';
  378. #ifdef AMIGA
  379.     if (!dfindOne(&filestat, s, 1) && filestat.fib_DirEntryType > 0) {
  380. #else
  381.     if (stat(s, &filestat) && filestat.st_mode & S_IFDIR) {
  382. #endif
  383.         name[-1] = '/';
  384.         name=s;
  385.     }
  386.     }
  387.     name = savestr(name);
  388. #ifdef AMIGA
  389.     free(s);
  390.     if (dfindOne(&filestat, name, 0) && !assume_exists) {
  391.         free(name);
  392.         name = Nullch;
  393.     }
  394. #else
  395.     Sprintf(tmpbuf, "RCS/%s", name);
  396.     free(s);
  397.     if (stat(name, &filestat) < 0 && !assume_exists) {
  398.     Strcat(tmpbuf, RCSSUFFIX);
  399.     if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+4, &filestat) < 0) {
  400.         Sprintf(tmpbuf, "SCCS/%s%s", SCCSPREFIX, name);
  401.         if (stat(tmpbuf, &filestat) < 0 && stat(tmpbuf+5, &filestat) < 0) {
  402.         free(name);
  403.         name = Nullch;
  404.         }
  405.     }
  406.     }
  407. #endif
  408.     return name;
  409. }
  410.